home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Talking Clock Pro™ 2.0b2 / Talking Clock Pro Source / Controller / Source / clwinrec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-04  |  11.0 KB  |  502 lines  |  [TEXT/KAHL]

  1. /*
  2.  * clwinrec.c
  3.  */
  4.  
  5. #include <AERegistry.h>
  6. #include <AEObjects.h>
  7.  
  8. #include <PlotIconSuite.h>
  9. #include "TalkConstants.h"
  10.  
  11. #include "apprec.h"
  12. #include "clwinrec.h"
  13. #include "x.h"
  14. #include "menu.h"
  15. #include "window.h"
  16. #include "util.h"
  17. #include "str.h"
  18.  
  19. #define MAX_SIZE 500
  20. #define MIN_SIZE 5
  21.  
  22.  
  23. DefWindowRec clwinRec = {
  24.  
  25.     129 , NULL ,
  26.  
  27.     ClwinCr ,
  28.     ClwinDe ,
  29.     ClwinUp ,
  30.     ClwinMD ,
  31.     ClwinMU ,
  32.     ClwinKD ,
  33.     ClwinAK ,
  34.     ClwinAc ,
  35.     NULL ,
  36.     ClwinId ,
  37.     ClwinPr ,
  38.     ClwinCo ,
  39.     ClwinAE
  40.  
  41. } ;
  42.  
  43.  
  44. typedef struct ClWinData {
  45.     Str32        fontName ;
  46.     short        fontSize ;
  47.     short        baseLine ;
  48.     short        winHeight ;
  49.     short        winWid ;
  50.     short        winX ;
  51.     short        winY ;
  52.     short        lastMin ;
  53.     short        lastSec ;
  54.     Boolean        showSecs ;
  55.     Boolean        smoothUpdates ;
  56.     Boolean        antiAlias ;
  57. } ClWinData , * ClWinPtr ;
  58.  
  59.  
  60. static short
  61. MaxDigWid ( void ) {
  62.  
  63. short wid = 0 ;
  64. char dig ;
  65. short w ;
  66.  
  67.     for ( dig = '0' ; dig <= '9' ; dig ++ ) {
  68.         w = CharWidth ( dig ) ;
  69.         if ( w > wid ) {
  70.             wid = w ;
  71.         }
  72.     }
  73.     return wid ;
  74. }
  75.  
  76.  
  77. static void
  78. ClWindowCalc ( ClWinPtr ptr , WindowPtr wp ) {
  79.  
  80. Str32 name ;
  81. FontInfo fi ;
  82. short num ;
  83. Point p = { 0 , 0 } ;
  84.  
  85.     SetPort ( wp ) ;
  86.     GetFNum ( ptr -> fontName , & num ) ;
  87.     TextFont ( num ) ;
  88.     TextSize ( ptr -> fontSize ) ;
  89.     GetFontInfo ( & fi ) ;
  90.     ptr -> baseLine = fi . ascent + fi . leading ;
  91.     ptr -> winHeight = ptr -> baseLine + fi . descent + fi . leading ;
  92.     ptr -> winWid = MaxDigWid ( ) * ( ptr -> showSecs ? 9 : 7 ) ;
  93.     LocalToGlobal ( & p ) ;
  94.     ptr -> winX = p . h ;
  95.     ptr -> winY = p . v ;
  96.     if ( ptr -> smoothUpdates ) {
  97.         if ( ! OffscreenAvailable ( ) ) {
  98.             ptr -> smoothUpdates = 0 ;
  99.         }
  100.     }
  101.     SizeWindow ( wp , ptr -> winWid , ptr -> winHeight , 1 ) ;
  102.     InvalRect ( & ( wp -> portRect ) ) ;
  103. }
  104.  
  105.  
  106. /*    A window is being created or opened. Allocate data and        */
  107. /*    select the window                                    */
  108. OSErr
  109. ClwinCr ( WindowPtr wp , Handle * data , FSSpec * file ) {
  110.  
  111. ClWinPtr ptr ;
  112. FontInfo fi ;
  113.  
  114.     ClWinAdd ( wp , app . data ) ;
  115.     * data = NewHandleClear ( sizeof ( ClWinData ) ) ;
  116.     HLockHi ( * data ) ;
  117.     ptr = ( ClWinPtr ) * * data ;
  118.     GetFontName ( GetAppFont ( ) , ptr -> fontName ) ;
  119.     ptr -> showSecs = 0 ;
  120.     ptr -> fontSize = GetDefFontSize ( ) ;
  121.     ClWindowCalc ( ptr , wp ) ;
  122.     SelectWindow ( wp ) ;
  123.     ShowWindow ( wp ) ;
  124.     return noErr ;
  125. }
  126.  
  127.  
  128. /*    Window is being destroyed. Put up a warning dialog, and        */
  129. /*    return errCancel if the user cancels closing - else call    */
  130. /*    DisposeWindow here                                            */
  131. OSErr
  132. ClwinDe ( WindowPtr wp , Handle data ) {
  133.  
  134.     ClWinRemove ( wp , app . data ) ;
  135.     DisposeHandle ( data ) ;
  136.     DisposeWindow ( wp ) ;
  137.     return noErr ;
  138. }
  139.  
  140.  
  141. /*    Update the window - BeginUpdate is already called            */
  142. OSErr
  143. ClwinUp ( WindowPtr wp , Handle data , EventRecord * event ) {
  144.  
  145. Str63 time ;
  146. unsigned long now ;
  147. ClWinPtr ptr = ( ClWinPtr ) * data ;
  148. short pos ;
  149. short num ;
  150. Boolean doSmooth = ptr -> smoothUpdates ;
  151. GWorldPtr lptr = NULL , sptr = NULL ;
  152. PixMapHandle lpix = NULL , spix = NULL ;
  153. Rect r , r2 ;
  154. short err ;
  155. Point p = { 0 , 0 } ;
  156. short mul = 1 ;
  157.  
  158.     GetDateTime ( & now ) ;
  159.     IUTimeString ( now , ptr -> showSecs , time ) ;
  160.     GetFNum ( ptr -> fontName , & num ) ;
  161.     TextFont ( num ) ;
  162.     TextSize ( ptr -> fontSize ) ;
  163.     pos = ( ptr -> winWid - StringWidth ( time ) ) / 2 ;
  164.  
  165.     if ( doSmooth ) {
  166.         r = wp -> portRect ;
  167.         LocalToGlobal ( & p ) ;
  168.         OffsetRect ( & r , p . h , p . v ) ;
  169.         err = NewGWorld ( & sptr , 0 , & r , NULL , NULL , useTempMem ) ;
  170.         OffsetRect ( & r , - p . h , - p . v ) ;
  171.     } else {
  172.         err = 1 ;
  173.     }
  174.     if ( ptr -> antiAlias && ! err ) {
  175.         r2 = wp -> portRect ;
  176.         if ( ptr -> fontSize > 24 ) {
  177.             r2 . right <<= 1 ;
  178.             r2 . bottom <<= 1 ;
  179.             mul = 2 ;
  180.         } else {
  181.             r2 . right <<= 2 ;
  182.             r2 . bottom <<= 2 ;
  183.             mul = 4 ;
  184.         }
  185.         err = NewGWorld ( & lptr , 0 , & r2 , NULL , NULL , useTempMem ) ;
  186.     }
  187.     if ( sptr && lptr && ! err ) {
  188.     GWorldPtr oldWorld ;
  189.     GDHandle oldGD ;
  190.         LockPixels ( GetGWorldPixMap ( lptr ) ) ;
  191.         GetGWorld ( & oldWorld , & oldGD ) ;
  192.         SetGWorld ( lptr , NULL ) ;
  193.         EraseRect ( & r2 ) ;
  194.         TextFont ( num ) ;
  195.         TextSize ( ptr -> fontSize * mul ) ;
  196.         MoveTo ( pos * mul , ptr -> baseLine * mul ) ;
  197.         DrawString ( time ) ;
  198.         LockPixels ( GetGWorldPixMap ( sptr ) ) ;
  199.         SetGWorld ( sptr , NULL ) ;
  200.         CopyBits ( ( BitMapPtr ) & ( ( ( GrafPtr ) lptr ) -> portBits ) ,
  201.             ( BitMapPtr ) & ( ( ( GrafPtr ) sptr ) -> portBits ) , & r2 , & r ,
  202.             ditherCopy , NULL ) ;
  203.         UnlockPixels ( GetGWorldPixMap ( lptr ) ) ;
  204.         SetGWorld ( oldWorld , oldGD ) ;
  205.     } else if ( sptr && ! err ) {
  206.     GWorldPtr oldWorld ;
  207.     GDHandle oldGD ;
  208.         LockPixels ( GetGWorldPixMap ( sptr ) ) ;
  209.         GetGWorld ( & oldWorld , & oldGD ) ;
  210.         SetGWorld ( sptr , NULL ) ;
  211.         EraseRect ( & r ) ;
  212.         TextFont ( num ) ;
  213.         TextSize ( ptr -> fontSize ) ;
  214.         MoveTo ( pos + r . left , ptr -> baseLine + r . top ) ;
  215.         DrawString ( time ) ;
  216.         SetGWorld ( oldWorld , oldGD ) ;
  217.     } else {
  218.         err = err ? err : 1 ;
  219.     }
  220.     doSmooth = ! err ;
  221.  
  222. /* Don't erase until we know what to do! */
  223.     if ( ! doSmooth ) {
  224.         EraseRect ( & ( wp -> portRect ) ) ;
  225.         MoveTo ( pos , ptr -> baseLine ) ;
  226.         DrawString ( time ) ;
  227.     } else {
  228.         CopyBits ( ( BitMapPtr ) & ( ( ( GrafPtr ) sptr ) -> portBits ) ,
  229.             & ( wp -> portBits ) , & r , & ( wp -> portRect ) , srcCopy , NULL ) ;
  230.     }
  231.     if ( lptr ) {
  232.         DisposeGWorld ( lptr ) ;
  233.     }
  234.     if ( sptr ) {
  235.         DisposeGWorld ( sptr ) ;
  236.     }
  237.  
  238.     return noErr ;
  239. }
  240.  
  241.  
  242. /*    The user clicked in your window. The window port is set and    */
  243. /*    event -> where is translated into local coordinates now        */
  244. OSErr
  245. ClwinMD ( WindowPtr wp , Handle data , EventRecord * event ) {
  246.  
  247. /* The framework has converted the point to local coordinates; convert back */
  248.     LocalToGlobal ( & ( event -> where ) ) ;
  249.     DragWindow ( wp , event -> where , & gDragLimit ) ;
  250. /* Save the new position */
  251.     ClWindowCalc ( ( ClWinPtr ) * data , wp ) ;
  252.     return noErr ;
  253. }
  254.  
  255.  
  256. /*    MouseUp in a window - you probably should do nothing        */
  257. OSErr
  258. ClwinMU ( WindowPtr wp , Handle data , EventRecord * event ) {
  259.  
  260.     return noErr ;
  261. }
  262.  
  263.  
  264. /*    The user typed in the window - command keys are already        */
  265. /*    taken care of and don't come here                            */
  266. OSErr
  267. ClwinKD ( WindowPtr wp , Handle data , EventRecord * event ) {
  268.  
  269.     return noErr ;
  270. }
  271.  
  272.  
  273. /*    You probably just want to call the KeyDown handler here        */
  274. OSErr
  275. ClwinAK ( WindowPtr wp , Handle data , EventRecord * event ) {
  276.  
  277.     return noErr ;
  278. }
  279.  
  280.  
  281. /*    Activate event - highlight/dehighlight controls & caret        */
  282. OSErr
  283. ClwinAc ( WindowPtr wp , Handle data , EventRecord * event ) {
  284.  
  285.     if ( event -> modifiers & activeFlag ) {
  286.         EnableCmd ( FONT_MENU , 0 ) ;
  287.         EnableCmd ( SIZE_MENU , 0 ) ;
  288.         EnableCmd ( CLOCK_MENU , 0 ) ;
  289.     } else {
  290.         DisableCmd ( FONT_MENU , 0 ) ;
  291.         DisableCmd ( SIZE_MENU , 0 ) ;
  292.         DisableCmd ( CLOCK_MENU , 0 ) ;
  293.     }
  294.     return noErr ;
  295. }
  296.  
  297.  
  298. /*    You should probably build a suitable activate event and        */
  299. /*    send to the activate handling for MultiFinder switches        */
  300. /*    In this application, we set this record field to NULL to        */
  301. /*    pass the event to the application instead.                */
  302. OSErr
  303. ClwinSw ( WindowPtr wp , Handle data , EventRecord * event ) {
  304.  
  305.     return noErr ;
  306. }
  307.  
  308.  
  309. /*    Idle time - set the sleep parameter if it's too large for    */
  310. /*    your needs. GetCaretTime() is a good value for text editors    */
  311. OSErr
  312. ClwinId ( WindowPtr wp , Handle data , long * sleep ) {
  313.  
  314.     return AppId ( wp , app . data , sleep ) ;
  315. }
  316.  
  317.  
  318. /*    This is called when menus need to be updated.                */
  319. OSErr
  320. ClwinPr ( WindowPtr wp , Handle data ) {
  321.  
  322. Str15 num ;
  323. ClWinPtr ptr = ( ClWinPtr ) * data ;
  324. short fNum ;
  325.  
  326.     FailErr ( AppPr ( wp , app . data ) ) ;
  327.     EnableCmd ( FILE_MENU , CLOSE_ITEM ) ;
  328.     SetPort ( wp ) ;
  329.     GetFNum ( ptr -> fontName , & fNum ) ;
  330.     EnableMenu ( FONT_MENU ) ;
  331.     EnableMenu ( SIZE_MENU ) ;
  332.     SizeMenuOutlines ( fNum ) ;
  333.     DisableCmd ( SIZE_MENU , SIZE_DELIMITER ) ;
  334.     CheckStr ( FONT_MENU , ptr -> fontName , 1 ) ;
  335.     NumToString ( ptr -> fontSize , num ) ;
  336.     CheckStr ( SIZE_MENU , num , 1 ) ;
  337.     EnableCmd ( CLOCK_MENU , SECONDS_ITEM ) ;
  338.     CheckCmd ( CLOCK_MENU , SECONDS_ITEM , ptr -> showSecs ) ;
  339.     if ( OffscreenAvailable ( ) ) {
  340.         EnableCmd ( CLOCK_MENU , SMOOTH_ITEM ) ;
  341.         CheckCmd ( CLOCK_MENU , SMOOTH_ITEM , ptr -> smoothUpdates ) ;
  342.         if ( ptr -> smoothUpdates ) {
  343.             EnableCmd ( CLOCK_MENU , ANTI_ALIAS_ITEM ) ;
  344.             CheckCmd ( CLOCK_MENU , ANTI_ALIAS_ITEM , ptr -> antiAlias ) ;
  345.         }
  346.     }
  347.     return noErr ;
  348. }
  349.  
  350.  
  351. /*    A menu selection was made - take appropriate action            */
  352. OSErr
  353. ClwinCo ( WindowPtr wp , Handle data , short menu , short item ,
  354.     unsigned char * itemStr ) {
  355.  
  356. ClWinPtr ptr = ( ClWinPtr ) * data ;
  357. long size ;
  358.  
  359.     if ( menu == FILE_MENU && item == CLOSE_ITEM ) {
  360.         DestroyWindow ( wp ) ;
  361.     } else if ( menu == FONT_MENU ) {
  362.         CopyPString ( itemStr , ptr -> fontName ) ;
  363.         ClWindowCalc ( ptr , wp ) ;
  364.     } else if ( menu == SIZE_MENU ) {
  365.         switch ( item ) {
  366.         case SMALLER_ITEM :
  367.             if ( ptr -> fontSize > MIN_SIZE ) {
  368.                 if ( KeyIsDown ( 0x3a ) ) {
  369.                     ptr -> fontSize >>= 1 ;
  370.                     if ( ptr -> fontSize < MIN_SIZE ) {
  371.                         ptr -> fontSize = MIN_SIZE ;
  372.                     }
  373.                 } else {
  374.                     ptr -> fontSize -- ;
  375.                 }
  376.             }
  377.             break ;
  378.         case LARGER_ITEM :
  379.             if ( ptr -> fontSize < MAX_SIZE ) {
  380.                 if ( KeyIsDown ( 0x3a ) ) {
  381.                     ptr -> fontSize <<= 1 ;
  382.                     if ( ptr -> fontSize > MAX_SIZE ) {
  383.                         ptr -> fontSize = MAX_SIZE ;
  384.                     }
  385.                 } else {
  386.                     ptr -> fontSize ++ ;
  387.                 }
  388.             }
  389.             break ;
  390.         default :
  391.             StringToNum ( itemStr , & size ) ;
  392.             ptr -> fontSize = size ;
  393.             break ;
  394.         }
  395.         ClWindowCalc ( ptr , wp ) ;
  396.     } else if ( menu == CLOCK_MENU ) {
  397.         switch ( item ) {
  398.         case SECONDS_ITEM :
  399.             ptr -> showSecs = ! ptr -> showSecs ;
  400.             break ;
  401.         case SMOOTH_ITEM :
  402.             ptr -> smoothUpdates = ! ptr -> smoothUpdates ;
  403.             break ;
  404.         case ANTI_ALIAS_ITEM :
  405.             ptr -> antiAlias = ! ptr -> antiAlias ;
  406.             break ;
  407.         }
  408.         ClWindowCalc ( ptr , wp ) ;
  409.     } else {
  410.         FailErr ( AppCo ( wp , app . data , menu , item , itemStr ) ) ;
  411.     }
  412.  
  413.     return noErr ;
  414. }
  415.  
  416.  
  417. /*    An AppleEvent was received with this window in front        */
  418. OSErr
  419. ClwinAE ( WindowPtr wp , Handle data , AppleEvent * event ,
  420.     AppleEvent * reply ) {
  421.  
  422.     return noErr ;
  423. }
  424.  
  425.  
  426. void
  427. ClWinWrite ( short refNum , WindowPtr wp ) {
  428.  
  429. DefWindowRec * dr ;
  430. long size ;
  431. ClWinData data ;
  432.  
  433.     if ( ! wp ) {
  434.         return ;
  435.     }
  436.     dr = RecFromWindow ( wp ) ;
  437.     if ( ! dr ) {
  438.         return ;
  439.     }
  440.     data = * ( ClWinPtr ) * ( dr -> data ) ;
  441.     size = sizeof ( ClWinData ) ;
  442.     FailErr ( FSWrite ( refNum , & size , ( Ptr ) & data ) ) ;
  443. }
  444.  
  445.  
  446. void
  447. ClWinRead ( short refNum , WindowPtr wp ) {
  448.  
  449. DefWindowRec * dr ;
  450. long size ;
  451. ClWinData data ;
  452. Point p ;
  453.  
  454.     size = sizeof ( ClWinData ) ;
  455.     FailErr ( FSRead ( refNum , & size , ( Ptr ) & data ) ) ;
  456.  
  457.     if ( ! wp ) {
  458.         return ;
  459.     }
  460.     dr = RecFromWindow ( wp ) ;
  461.     if ( ! dr ) {
  462.         return ;
  463.     }
  464.     * ( ClWinPtr ) * ( dr -> data ) = data ;
  465.     p . h = data . winX + 10 ;
  466.     p . v = data . winY + 5 ;
  467.     if ( PtInRgn ( p , GetGrayRgn ( ) ) ) {
  468.         MoveWindow ( wp , data . winX , data . winY , 1 ) ;
  469.     }
  470.     ClWindowCalc ( ( ClWinPtr ) * ( dr -> data ) , wp ) ;
  471. }
  472.  
  473.  
  474. void
  475. ClWinRunClock ( WindowPtr wp , long * sleep , short nowMin , short nowSec ) {
  476.  
  477. long canSleep ;
  478. DefWindowRec * dr ;
  479. ClWinPtr ptr ;
  480.  
  481.     if ( ! wp ) {
  482.         return ;
  483.     }
  484.     dr = RecFromWindow ( wp ) ;
  485.     if ( ! dr ) {
  486.         return ;
  487.     }
  488.     ptr = ( ClWinPtr ) * ( dr -> data ) ;
  489.  
  490.     canSleep = ptr -> showSecs ? 10 : 180 ;
  491.     if ( * sleep > canSleep ) {
  492.         * sleep = canSleep ;
  493.     }
  494.     if ( ( nowMin != ptr -> lastMin ) ||
  495.         ( ptr -> showSecs && ( nowSec != ptr -> lastSec ) ) ) {
  496.         SetPort ( wp ) ;
  497.         ptr -> lastMin = nowMin ;
  498.         ptr -> lastSec = nowSec ;
  499.         ClwinUp ( wp , dr -> data , NULL ) ;
  500.     }
  501. }
  502.